package;

import nme.display.MovieClip;
import nme.display.SimpleButton;
import nme.events.MouseEvent;
import nme.events.KeyboardEvent;
import nme.events.Event;
import nme.display.Bitmap;
import nme.ui.Keyboard;
import nme.ui.Mouse;
import nme.Lib;
import nme.text.TextFormat;
import nme.text.TextField;
import com.eclecticdesignstudio.spritesheet.importers.SpriteLoq;
import com.eclecticdesignstudio.spritesheet.AnimatedSprite;

/**
 * @author jonathanmoriarty
 */
 // 720 x 405
 // health bar / character name / time limit (1:00) / round counter / best 2 out of 3
 // selecting you char matches you with random opponent
class PlayScreen extends MovieClip, implements Screen
{
	private var _currTime:Int;
	private var _prevTime:Int;
	private var _deltaTime:Int;
	
	public static var pauseScreen:PauseScreen;
	
	inline private static var INPUT_MAX:Int = 10;
	inline private static var MAX_KEY_DELAY:Int = 300;
	
	inline private static var PLAYER_1_START_X:Float = 100;
	inline private static var PLAYER_2_START_X:Float = 600;
	
	inline private static var BAR_BASE_X:Float = 102;
	inline private static var BAR_BASE_X_2:Float = 619;
	inline private static var BAR_BASE_Y:Float = 340;
	
	inline private static var TIME_DISPLAY_X:Int = 324;
	inline private static var TIME_DISPLAY_Y:Int = 359;
	
	inline private static var TIME_MAX:Int = 91000;
	private var _timeRemaining:Int;
	
	public static var inputQueue:Array<Dynamic>;
	public static var lastKeyDelay:Int;
	
	// TODO: Add an animated background. (Parallax scrolling?)
	//public var level:Level
	/*
		Level object should update based on player movements, 
		holds bitmap data for latyers, parallax scrolling, 
		and optional environmental hazards
	*/
	private var _background:Bitmap;
	private var _ground:Bitmap;
	
	inline private static var GROUND_LEVEL:Int = 330;
	
	private var _uiBase:Bitmap;
	
	private var _healthBar1:HealthDisplay;
	private var _healthBar2:HealthDisplay;
	
	private var _timeDisplay:TimeDisplay;
	
	private var _gameOver:Bool;
	
	public static var players:Array<Dynamic>;
	
	public function new( l_character0:Int, l_character1:Int ) 
	{
		super();
		addEventListener( Event.REMOVED_FROM_STAGE, onRemoved );
		
		inputQueue = new Array<Dynamic>();
		lastKeyDelay = 0;
		
		makeLevel();
		makePlayers( l_character0, l_character1 );
		makeUI();
		
		_gameOver = false;
		pauseScreen = null;
		Mouse.hide();
		
		show();
		_prevTime = Lib.getTimer();
		Lib.current.stage.addEventListener( Event.ENTER_FRAME, update );
	}
	
	public function makePlayers( l_character0:Int, l_character1:Int ):Void
	{
		players = new Array<Dynamic>();
		
		var l_playerOne:HumanPlayer = null;
		
		if ( l_character0 == 0 )
		{
			l_playerOne = new HumanPlayer( "kliibu", PLAYER_1_START_X, PlayScreen.getGroundLevel( PLAYER_1_START_X ), 1 );
		}
		else if ( l_character0 == 1 )
		{
			l_playerOne = new HumanPlayer( "kwigaan", PLAYER_1_START_X, PlayScreen.getGroundLevel( PLAYER_1_START_X ), 1 );
		}
		else
		{
			l_playerOne = new HumanPlayer( "quarren", PLAYER_1_START_X, PlayScreen.getGroundLevel( PLAYER_1_START_X ), 1 );
		}
		addChild( l_playerOne );
		players.push( l_playerOne );
		
		var l_playerTwo:HumanPlayer = null;
		
		if ( l_character1 == 0 )
		{
			l_playerOne = new HumanPlayer( "kliibu", PLAYER_2_START_X, PlayScreen.getGroundLevel( PLAYER_2_START_X ), -1 );
		}
		else if ( l_character1 == 1 )
		{
			l_playerOne = new HumanPlayer( "kwigaan", PLAYER_2_START_X, PlayScreen.getGroundLevel( PLAYER_2_START_X ), -1 );
		}
		else
		{
			l_playerOne = new HumanPlayer( "quarren", PLAYER_2_START_X, PlayScreen.getGroundLevel( PLAYER_2_START_X ), -1 );
		}
		addChild( l_playerOne );
		players.push( l_playerOne );
	}
	
	public function makeLevel():Void
	{
		_background = Tools.loadBitmap( "background_0" );
		_background.x = 0;
		_background.y = -60;
		addChild( _background );
		
		_ground = Tools.loadBitmap( "ground_0" );
		_ground.x = 0;
		_ground.y = 0;
		addChild( _ground );
	}
	
	public function makeUI():Void
	{
		_uiBase = Tools.loadBitmap( "bar_base" );
		_uiBase.x = BAR_BASE_X;
		_uiBase.y = BAR_BASE_Y;
		addChild( _uiBase );
		
		
		_healthBar1 = new HealthDisplay( BAR_BASE_X, BAR_BASE_Y, 0, 100, players[0].getHealth() );
		addChild( _healthBar1 );
		
		_healthBar2 = new HealthDisplay( BAR_BASE_X_2, BAR_BASE_Y, 0, 100, players[0].getHealth() );
		_healthBar2.scaleX = -1;
		addChild( _healthBar2 );
		
		_timeRemaining = TIME_MAX;
		
		_timeDisplay = new TimeDisplay( TIME_DISPLAY_X, TIME_DISPLAY_Y, 0, TIME_MAX, _timeRemaining );
		addChild( _timeDisplay );
	}
		
	public function onRemoved( event:Event ):Void
	{		
		if ( Lib.current.stage.hasEventListener( Event.ENTER_FRAME ) )
		{
			Lib.current.stage.removeEventListener( Event.ENTER_FRAME, update );
		}
		if ( hasEventListener( Event.REMOVED_FROM_STAGE ) ) 
		{
   			removeEventListener( Event.REMOVED_FROM_STAGE, onRemoved );
		}
	}
	
	public static function getGroundLevel( l_currentX:Float ):Float 
	{
		return GROUND_LEVEL;
	}
	
	public function updatePlayers( l_deltaTime:Int ):Void 
	{
		var l_tempFix:Int = 0;
		for (l_player in players)
		{
			if ( Std.is(l_player, HumanPlayer) && l_tempFix == 0 )
			{
				/*var l_tempInputQueue:Array<Dynamic> = inputQueue.copy();
				if ( InputManager.isKeyPressed( InputManager.P_KEY ) )
				{
					l_tempInputQueue.push("punch");
				}
				else if ( InputManager.isKeyPressed( InputManager.K_KEY ) )
				{
					l_tempInputQueue.push("kick");
				}*/
				l_player.update( l_deltaTime, inputQueue );
			}
			else
			{
				var l_tempX:Float = l_player.x;
				l_player.scaleX *= -1;
				l_player.update( l_deltaTime, inputQueue );
				l_player.x += ( l_tempX - l_player.x ) * 2;
			}
			l_tempFix++;
		
		}
		
		
		/*
		
		for player in players
		{
			if (human)
			{
				make temporary cop of InputQueue that includes currently pressed buttons
				humanPlayer.update (l_deltaTime, InputQueue)
			}
			else
			{
				AIPlayer.update (l_deltaTime, (humanPlayer?))
			}
		}
		
		update a player code
		if (!executing a combo)
		{
			
		}
		
		_player.sprite.update(l_deltaTime);
		
		*/
	}
	
	public function updateUI( l_deltaTime:Int ):Void 
	{
		//players[1].updateHealth(-3);
		_healthBar1.update( l_deltaTime, players[0].getHealth() );
		
		_healthBar2.update( l_deltaTime, players[1].getHealth() );
		
		_timeRemaining -= l_deltaTime;
		_timeDisplay.update( l_deltaTime, _timeRemaining );
	}
	
	/*public function noKeysPressed():Bool
	{
		return !InputManager.isKeyPressed( InputManager.LEFT_KEY ) && !InputManager.isKeyPressed( InputManager.RIGHT_KEY );
	}*/
	
	public function updateInputs( l_deltaTime:Int ):Void 
	{
		if ( inputQueue.length > INPUT_MAX )
		{
			inputQueue.shift();
		}
		//TODO: update this
		if ( inputQueue.length > 0 )
		{
			lastKeyDelay += l_deltaTime;
		}
		
		if ( InputManager.isKeyReleased( InputManager.LEFT_KEY ) )
		{
			inputQueue.push(InputManager.LEFT_KEY);
			lastKeyDelay = 0;
		}
		if ( InputManager.isKeyReleased( InputManager.RIGHT_KEY ) )
		{
			inputQueue.push(InputManager.RIGHT_KEY);
			lastKeyDelay = 0;
		}
		
		
		if ( lastKeyDelay >= MAX_KEY_DELAY )
		{
			inputQueue = null;
			inputQueue = new Array<Dynamic>();
			lastKeyDelay = 0;
		}
		//trace( inputQueue );
	}
	
	public function update( l_event:Event ):Void 
	{	
		_currTime = Lib.getTimer();
		_deltaTime = _currTime - _prevTime;
		_prevTime = _currTime;
		
		if ( InputManager.isKeyPressed( InputManager.ENTER_KEY ) )
		{
			trace(InputManager.isKeyPressed( InputManager.ENTER_KEY ));
		}
		
		if ( pauseScreen == null && InputManager.isKeyPressed( InputManager.ENTER_KEY ) )
		{
			trace("PAUSE");
			InputManager.update();
			pauseScreen = new PauseScreen();
			addChild(pauseScreen);
		}
		
		if ( pauseScreen == null )
		{
			if ( !_gameOver )
			{
				updateInputs( _deltaTime );
				updatePlayers( _deltaTime );
				updateUI( _deltaTime );
			}
			if ( _gameOver )
			{
				dispatchEvent( new NavigationEvent( NavigationEvent.SELECT ) );
			}
		}
		else
		{
			pauseScreen.update( _deltaTime );
			if ( pauseScreen.confirmed )
			{
				var l_selected:Int = pauseScreen.getSelectedOption();
				if ( l_selected == 0 )
				{
					removeChild(pauseScreen);
					pauseScreen = null;
				}
				else if ( l_selected == 1 )
				{
					removeChild(pauseScreen);
					pauseScreen = null;
				}
				else
				{
					removeChild(pauseScreen);
					pauseScreen = null;
					InputManager.update();
					dispatchEvent( new NavigationEvent( NavigationEvent.MENU ) );
				}
			}
		}
	}
	
	public function show():Void
	{
		this.visible = true;
	}
	
	public function hide():Void
	{
		this.visible = false;
	}
	
	public function reset():Void
	{
		// nothing needed here at the moment.
	}
	
	public function destroy():Void
	{
		hide();
	}

}